package com.liuzy.crawler.core;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import com.liuzy.crawler.util.FileUtil;

/**
 * @author liuzy
 * @since 2015年9月23日
 */
public class FileSave {
	public static void main(String[] args) {
		String url = "www.taobao.com";
		String saveDir = "D:\\_DownLoad\\_cache\\";
		String fileName = FileUtil.buildFileName(url);
		FileSave fileSave = new FileSave(url, saveDir, fileName);
		fileSave.saveCache();
		System.out.println("地址:" + url);
		System.out.println("编码:" + fileSave.getCharset());
		System.out.println("耗时:" + fileSave.getUseTime() + "ms");
	}

	private String url;
	private File file;
	private String saveDir;
	private String fileName;
	private int minKB = 10;
	private int maxKB = 1024 * 8;
	private int timeout = 5000;
	private String charset;
	private HttpURLConnection conn = null;
	private InputStream inputStream = null;
	private FileOutputStream fileOutputStream = null;
	private long useTime = System.currentTimeMillis();

	public FileSave(String url, String saveDir, String fileName) {
		this.url = url;
		this.saveDir = FileUtil.creteDir(saveDir);
		this.fileName = fileName;
		this.file = new File(this.saveDir + this.fileName);
	}

	/**
	 * 识别编码读字符串写
	 */
	public int saveCache() {
		try {
			inputStream = getInputStream(url.trim());
			String pageStr = readStream(inputStream);
			fileOutputStream = new FileOutputStream(file);
			fileOutputStream.write(pageStr.getBytes());
		} catch (Exception e) {
			System.out.println(fileName + ":" + e.getMessage());
			return 4;
		} finally {
			close();
		}
		return 0;
	}

	/**
	 * 边读边写
	 */
	public int saveImage() {
		try {
			inputStream = getInputStream(url.trim());
			fileOutputStream = new FileOutputStream(file);
			byte[] buffer = new byte[1024];
			int len = 0;
			int kb = 0;
			while ((len = inputStream.read(buffer)) != -1) {
				if (kb > maxKB) {// 文件大于8MB停止下载
					break;
				} else {
					++kb;
					fileOutputStream.write(buffer, 0, len);
				}
			}
			if (kb < minKB) {// 小于10KB
				file.delete();
				return 2;
			} else if (kb > maxKB) {// 大于8MB
				file.delete();
				return 3;
			} else {
				return 0;
			}
		} catch (Exception e) {
			System.out.println(fileName + "|" + e.getMessage());
			return 4;
		} finally {
			close();
		}
	}

	private InputStream getInputStream(String url) throws Exception {
		if (!url.startsWith("http://"))
			url = "http://" + url;
		URL uri = new URL(url);
		HttpURLConnection conn = (HttpURLConnection) uri.openConnection();
		conn.setRequestMethod("GET");
		conn.setConnectTimeout(timeout);
		conn.setReadTimeout(timeout);
		return conn.getInputStream();
	}

	public String readStream(InputStream inputStream) throws Exception {
		ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
		byte[] buffer = new byte[1024];
		int len = -1;
		while ((len = inputStream.read(buffer)) != -1) {
			outSteam.write(buffer, 0, len);
		}
		outSteam.close();
		inputStream.close();
		byte[] bytes = outSteam.toByteArray();
		readChaset(bytes);
		return new String(bytes, charset);
	}

	private void readChaset(byte[] bytes) {
		String temp;
		if (bytes.length < 512) {
			temp = new String(bytes);
		} else {
			StringBuilder sb = new StringBuilder();
			for (int i = 0; i < 512; i++) {
				sb.append((char) bytes[i]);
			}
			temp = sb.toString();
		}
		temp = temp.replaceAll(" ", "").toLowerCase();
		if (temp.contains("=utf8") 
				|| temp.contains("=\'utf8") 
				|| temp.contains("=\"utf8") 
				|| temp.contains("=utf-8") 
				|| temp.contains("=\'utf-8") 
				|| temp.contains("=\"utf-8") ) {
			this.charset = "UTF-8";
		} else if (temp.contains("=gb2312") 
				|| temp.contains("=\'gb2312") 
				|| temp.contains("=\"gb2312")) {
			this.charset = "gb2312";
		} else if (temp.contains("=gbk")
				|| temp.contains("=\'gbk")
				|| temp.contains("=\"gbk")) {
			this.charset = "gbk";
		} else {
			this.charset = "ISO-8859-1";
		}
	}

	private void close() {
		try {
			if (fileOutputStream != null)
				fileOutputStream.close();
			if (inputStream != null)
				inputStream.close();
			if (conn != null)
				conn.disconnect();
		} catch (Exception e1) {
			e1.printStackTrace();
		}
		this.useTime = System.currentTimeMillis() - useTime;
	}

	public String getCharset() {
		return charset;
	}

	public long getUseTime() {
		return useTime;
	}
}
